<?php

namespace plugin\ycMassage\app\controller;

use plugin\ycMassage\app\BaseController;
use plugin\ycMassage\app\model\MassageUser;
use plugin\ycMassage\app\model\MassageUserDealer;
use plugin\ycMassage\app\model\MassageUserWechat;
use plugin\ycMassage\utils\enum\State;
use support\Request;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;

class LoginController extends BaseController
{
    public function wechatLoginCallback(Request $request)
    {
        $code = $request->get('code');
        $state = $request->get('state');
        $stateObj = Cache::pull($state);
        if (!$stateObj) {
            return $this->authFail(null, ['code' => 1, 'msg' => 'state参数错误']);
        }
        $appid = $stateObj->appid;
        $wxappid = getHpConfig('appid', $appid, 'wx');
        $wxsecret = getHpConfig('secret', $appid, 'wx');
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wxappid}&secret={$wxsecret}&code={$code}&grant_type=authorization_code";
        $Client = new \GuzzleHttp\Client();
        $response = $Client->request('GET', $url);
        $body = $response->getBody();
        $data = json_decode($body);
        if (isset($data->errcode)) {
            return $this->authFail($appid, ['code' => $data->errcode, 'msg' => $data->errmsg]);
        }
        $MassageUserWechat = null;
        if (isset($data->unionid)) {
            $MassageUserWechat = MassageUserWechat::where(['saas_appid' => $appid, 'unionid' => $data->unionid])->find();
        }
        if (!$MassageUserWechat) {
            $MassageUserWechat = MassageUserWechat::where(['saas_appid' => $appid, 'openid' => $data->openid])->find();
        }
        $wxUserInfo = null;
        try {
            $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$data->access_token}&openid={$data->openid}&lang=zh_CN";
            $response = $Client->request('GET', $url);
            $body = $response->getBody();
            $wxUserInfo = json_decode($body);
            if (isset($wxUserInfo->errcode)) {
                throw new \Exception("获取微信用户信息失败：{$wxUserInfo->errmsg}【{$wxUserInfo->errcode}】");
            }
        } catch (\Throwable $th) {
            $wxUserInfo = null;
            Log::error($th->getMessage());
        }
        Db::startTrans();
        try {
            $isRegister = false;
            if ($MassageUserWechat && $MassageUserWechat->uid) {
                # 登录并更新用户信息
                $MassageUser = MassageUser::where(['id' => $MassageUserWechat->uid])->find();
                if ($MassageUser->state === State::NO['value']) {
                    throw new \Exception('该用户已被冻结');
                }
            } else {
                $pModel = MassageUser::where(['saas_appid' => $appid, 'id' => $stateObj->puid])->find();
                if (!$MassageUserWechat) {
                    $MassageUserWechat = new MassageUserWechat;
                    $MassageUserWechat->saas_appid = $appid;
                }
                # 注册并登录
                $MassageUser = new MassageUser;
                $MassageUser->saas_appid = $appid;
                if ($pModel) {
                    $isRegister = true;
                    $MassageUser->puid = $pModel->id;
                }
                $MassageUser->nickname = $wxUserInfo->nickname;
                $MassageUser->headimg = $wxUserInfo->headimgurl;
                $dealerModel = MassageUser::where(['id' => $stateObj->dealer_uid])->find();
                if ($dealerModel) {
                    $MassageUser->dealer_uid = $dealerModel->id;
                    MassageUserDealer::IncPeopleNum($dealerModel->id);
                }
            }
            $MassageUserWechat->openid = $data->openid;
            if (isset($data->unionid)) {
                $MassageUserWechat->unionid = $data->unionid;
            }
            if (isset($data->subscribe)) {
                $MassageUserWechat->subscribe = $data->subscribe;
            }
            if ($wxUserInfo) {
                $MassageUserWechat->nickname = $wxUserInfo->nickname;
                $MassageUserWechat->headimg = $wxUserInfo->headimgurl;
            }
            $MassageUser->last_login_ip = $request->ip();
            $MassageUser->last_login_time = date('Y-m-d H:i:s');
            $MassageUser->save();
            if ($isRegister) {
                # 邀新奖励业务
                MassageUser::NewRegisterGift($MassageUser, $pModel);
                # 邀新奖励业务
            }
            $MassageUserWechat->uid = $MassageUser->id;
            $MassageUserWechat->save();
            Db::commit();
        } catch (\Throwable $th) {
            Db::rollback();
            return $this->authFail($appid, ['code' => 1, 'msg' => $th->getMessage()]);
        }
        $token = $MassageUser::getToken($MassageUser);
        return $this->authSuccess($stateObj, urlencode($token));
    }
    private function authFail($appid, $data)
    {
        $domain = getHpConfig('domain', (int)$appid, 'plugins_domains');
        return redirect("{$domain}/app/ycMassage/#/pages/login/callback?errcode={$data['code']}&msg={$data['msg']}&appid={$appid}");
    }
    private function authSuccess($stateObj, $token = '')
    {
        $domain = getHpConfig('domain', (int)$stateObj->appid, 'plugins_domains');
        $url = "{$domain}/app/ycMassage/#/";
        switch ($stateObj->redirect) {
            case 'user':
                $url = "{$url}pages/user/index?token={$token}&action={$stateObj->action}&appid={$stateObj->appid}";
                break;
            case 'bind':
                $url = "{$url}pages/user/account/bind?appid={$stateObj->appid}";
                break;
            case 'technician':
                $url = "{$url}pages/technician/details?token={$token}&appid={$stateObj->appid}&id={$stateObj->action}";
                break;
            case 'technician-verification':
                $url = "{$url}technician/pages/index/verification?token={$token}&code={$stateObj->action}&appid={$stateObj->appid}";
                break;
            case 'technician-apply':
                $url = "{$url}technician/pages/user/apply?token={$token}&appid={$stateObj->appid}";
                break;
            default:
                if($stateObj->redirect){
                    $url = "{$url}{$stateObj->redirect}?token={$token}&appid={$stateObj->appid}";
                    if(isset($stateObj->params)&&$stateObj->params){
                        $url = "{$url}&".http_build_query($stateObj->params);
                    }
                }else{
                    $url = "{$url}?token={$token}&appid={$stateObj->appid}";
                }
                break;
        }
        return redirect($url);
    }
    public function wechatBindCallback(Request $request)
    {
        $code = $request->get('code');
        $state = $request->get('state');
        $stateObj = Cache::pull($state);
        if (!$stateObj) {
            return $this->authFail(null, ['code' => 1, 'msg' => 'state参数错误']);
        }
        $appid = $stateObj->appid;
        $wxappid = getHpConfig('appid', $appid, 'wx');
        $wxsecret = getHpConfig('secret', $appid, 'wx');
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wxappid}&secret={$wxsecret}&code={$code}&grant_type=authorization_code";
        $Client = new \GuzzleHttp\Client();
        $response = $Client->request('GET', $url);
        $body = $response->getBody();
        $data = json_decode($body);
        if (isset($data->errcode)) {
            return $this->authFail($appid, ['code' => $data->errcode, 'msg' => $data->errmsg]);
        }
        $MassageUserWechat = null;
        if (isset($data->unionid)) {
            $MassageUserWechat = MassageUserWechat::where(['saas_appid' => $appid, 'unionid' => $data->unionid])->find();
        }
        if (!$MassageUserWechat) {
            $MassageUserWechat = MassageUserWechat::where(['saas_appid' => $appid, 'openid' => $data->openid])->find();
        }
        $MassageUser = MassageUser::where(['id' => $stateObj->uid])->find();
        if (!$MassageUser) {
            return $this->authFail($appid, ['code' => 1, 'msg' => '请先登录再绑定']);
        }
        if (MassageUserWechat::where(['uid' => $MassageUser->id])->count()) {
            return  $this->authFail($appid, ['code' => 1, 'msg' => '该账号已绑定微信，请刷新查看']);
        }
        if ($MassageUserWechat) {
            if ($MassageUserWechat->uid) {
                return  $this->authFail($appid, ['code' => 1, 'msg' => '该微信已绑定其他账号']);
            }
        } else {
            $MassageUserWechat = new MassageUserWechat;
            $MassageUserWechat->saas_appid = $appid;
        }
        $MassageUserWechat->openid = $data->openid;
        if (isset($data->unionid)) {
            $MassageUserWechat->unionid = $data->unionid;
        }
        if (isset($data->subscribe)) {
            $MassageUserWechat->subscribe = $data->subscribe;
        }
        $MassageUserWechat->uid = $MassageUser->id;
        if ($MassageUserWechat->save()) {
            return $this->authSuccess($stateObj);
        }
        return $this->authFail($appid, ['code' => 1, 'msg' => '微信绑定失败']);
    }
}
